#ifndef __TCP_CLIENT_HPP__
#define __TCP_CLIENT_HPP__

#include "TaskPackage.hpp"
#include "baseSession.hpp"
#include <boost/asio.hpp>
#include <cstdlib>
#include <iostream>
#include <queue>
#include <thread>

using boost::asio::ip::tcp;
using namespace std;

class tcpClient : public baseSession {
public:
  tcpClient(boost::asio::io_context &io_context,
            const tcp::resolver::results_type &endpoints,
            std::queue<csn::TaskPackage_ptr> &recv_pkg_que)
      : baseSession(io_context, recv_pkg_que,
                    std::move(tcp::socket(io_context))) {
    do_connect(endpoints);
  }
  void write(csn::TaskPackage_ptr pkg) {
    wpkg_ = pkg;
    boost::asio::post(io_context_, [this]() { do_write(); });
  }
  void close() {
    boost::asio::post(io_context_, [this]() { socket_.close(); });
  }
  bool is_connected() { return ok_; }

private:
  virtual void err_handler() {
    cout << "error occured, close" << endl;
    socket_.close();
  };
  void do_connect(const tcp::resolver::results_type &endpoints) {
    boost::asio::async_connect(
        socket_, endpoints,
        [this](boost::system::error_code ec, tcp::endpoint) {
          if (!ec) {
            ok_ = true;
            do_read_header();
          } else {
            socket_.close();
            err_handler();
          }
        });
  }

private:
  bool ok_ = false;
};

#endif // __TCP_CLIENT_HPP__
